home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / liblinuxlive < prev    next >
Text File  |  2006-05-11  |  13KB  |  470 lines

  1. #!/bin/ash
  2.  
  3. # Functions library :: for Linux Live scripts 5.x.y
  4. # Author: Tomas M. <http://www.linux-live.org>
  5. #
  6.  
  7. # ===========================================================
  8. # variables
  9. # ===========================================================
  10.  
  11. # linux live flag to fstab, if fstab line doesn't contain it,
  12. # never remove it from fstab automatically (user added it)
  13. FSTABLLFLAG="# Auto-Update"
  14.  
  15. # ===========================================================
  16. # user interface functions
  17. # ===========================================================
  18.  
  19. # echolog
  20. # $1 = text to show and to write to /var/log/messages
  21. #
  22. echolog()
  23. {
  24.    echo "LIVECD:" "$@" >>/var/log/livedbg
  25.    echo "$@"
  26. }
  27.  
  28. # debug
  29. # commands executed when debug boot parameter is present
  30. #
  31. debug()
  32. {
  33.    echo
  34.    echo "====="
  35.    echo ": Debugging started. Here is the root shell for you."
  36.    echo ": Type your desired command or hit Ctrl+D to continue booting."
  37.    echo
  38.    ash
  39. }
  40.  
  41. # header
  42. # $1 = text to show
  43. #
  44. header()
  45. {
  46.    echolog "$1"
  47. }
  48.  
  49. fatal()
  50. {
  51.    echolog
  52.    header "Fatal error occured - $1"
  53.    echolog "Something went wrong and we can't continue. This should never happen."
  54.    echolog "Please reboot your computer with Ctrl+Alt+Delete ..."
  55.    echolog
  56.    ash
  57. }
  58.  
  59. allow_only_root()
  60. {
  61.   # test if the script is started by root user. If not, exit
  62.   if [ "0$UID" -ne 0 ]; then
  63.      echo "Only root can run `basename $0`"; exit 1
  64.   fi
  65. }
  66.  
  67. # ===========================================================
  68. # text processing functions
  69. # ===========================================================
  70.  
  71. # egrep_o is a replacement for "egrep -o". It prints only the last
  72. # matching text
  73. # $1 = regular expression
  74. #
  75. egrep_o()
  76. {
  77.    cat | egrep "$1" | sed -r "s/.*($1).*/\\1/"
  78. }
  79.  
  80. # look into cmdline and echo $1 back if $1 is set
  81. # $1 = value name, case sensitive, for example livecd_subdir
  82. # $2 = file to use instead /proc/cmdline, optional
  83. #
  84. cmdline_parameter()
  85. {
  86.    CMDLINE=/proc/cmdline
  87.    if [ "$2" != "" ]; then CMDLINE="$2"; fi
  88.    cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1(\$|=|[[:space:]]+)" | egrep_o "$1"
  89. }
  90.  
  91. # look into cmdline and echo value of $1 option
  92. # $1 = value name, case sensitive, for example livecd_subdir
  93. # $2 = file to use instead /proc/cmdline, optional
  94. #
  95. cmdline_value()
  96. {
  97.    CMDLINE=/proc/cmdline
  98.    if [ "$2" != "" ]; then CMDLINE="$2"; fi
  99.    cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1=([^[:space:]]+)" | egrep_o "=.*" | cut -b 2- | tail -n 1
  100. }
  101.  
  102. # ===========================================================
  103. # system functions
  104. # ===========================================================
  105.  
  106. # modprobe module $1, including all dependencies, suppress all messages
  107. # (own function because modprobe in busybox doesn't work with gzipped modules)
  108. # $1 = module name, eg. ehci-hcd
  109. # $2 = optional argument
  110. #
  111. modprobe_module()
  112. {
  113.   if [ "$1" = "" ]; then return 1; fi
  114.   PRINTK=`cat /proc/sys/kernel/printk`
  115.   echo "0" >/proc/sys/kernel/printk
  116.  
  117.   KERNEL="`uname -r`"; LSMOD=/tmp/_lsmod
  118.   MODULEDEPS="`cat /lib/modules/$KERNEL/modules.dep | egrep \"$1\\.ko(\\.gz)?:\"`"
  119.  
  120.   for MODULE in `echo $MODULEDEPS | cut -d ":" -f 2-` `echo $MODULEDEPS | cut -d ":" -f 1`; do
  121.      TMPMOD="/tmp/`basename $MODULE .gz`";
  122.      # if the module is not loaded already
  123.      if [ "`cat $LSMOD 2>/dev/null | egrep \"^$TMPMOD\\\$\"`" = "" ]; then
  124.         gunzip -c $MODULE 2>/dev/null >$TMPMOD
  125.         if [ "$?" -ne 0 ]; then cp $MODULE $TMPMOD; fi # can't gunzip? copy
  126.         insmod $TMPMOD $2 >/dev/null 2>/dev/null; err=$?
  127.         if [ "$err" -eq 0 ]; then echo $TMPMOD >>$LSMOD; fi # module log
  128.         rm $TMPMOD
  129.      fi
  130.   done
  131.  
  132.   echo "$PRINTK" >/proc/sys/kernel/printk
  133.   if [ "$err" -ne 0 ]; then echolog "error inserting module $1 ($err) for your kernel `uname -r`"; fi
  134.   return $err
  135. }
  136.  
  137. # Mount device $1 to $2
  138. # $1 = /dev device to mount, eg. /dev/hda1
  139. # $2 = mountpoint, eg. /mnt/hda1
  140. # $3 = mount options, for example "loop", "ro", or "remount,rw"
  141. # $4 = filesystem type
  142. #
  143. mount_device()
  144. {
  145.   mkdir -p $2
  146.   if [ "$3" != "" ]; then OPTIONS="-o $3"; else OPTIONS=""; fi
  147.   if [ "$4" != "" ]; then FILESYSTEM="-t $4"; else FILESYSTEM=""; fi
  148.  
  149.   PRINTK=`cat /proc/sys/kernel/printk`
  150.   echo "0" >/proc/sys/kernel/printk
  151.  
  152.   mount $FILESYSTEM $1 $2 $OPTIONS >/dev/null 2>/dev/null
  153.   err=$?
  154.  
  155.   if [ "$err" -ne 0 ]; then rmdir $2 2>/dev/null; fi
  156.   echo "$PRINTK" >/proc/sys/kernel/printk
  157.   return $err
  158. }
  159.  
  160. # ===========================================================
  161. # live module functions
  162. # ===========================================================
  163.  
  164. # Create module
  165. # call mksquashfs with apropriate arguments
  166. # $1 = directory which will be compressed to squashfs module
  167. # $2 = output .mo file
  168. # $3 = optional -keep-as-directory argument
  169. #
  170. create_module()
  171. {
  172.    mksquashfs "$1" "$2" $3 >/dev/null
  173.    if [ $? -ne 0 ]; then return 1; fi
  174.    chmod oga-x "$2" # remove execute attrib
  175. }
  176.  
  177. # Mount .mo module to destination directory
  178. # $1 = path to .mo livecd compressed module
  179. # $2 = destination folder
  180. #
  181. mount_module()
  182. {
  183.    mount -t squashfs -o loop,ro "$1" "$2"
  184.    err=$?
  185.    if [ $err -eq 0 ]; then
  186.       echo "$1 $2" >>/tmp/_mounts
  187.    fi
  188.    return $err
  189. }
  190.  
  191. # Insert a directory tree $2 to an union specified by $1
  192. # Top-level read-write branch is specified by it's index 0
  193. # $1 = union absolute path (starting with /)
  194. # $2 = path to data directory
  195. #
  196. union_insert_dir()
  197. {
  198.    unionctl "$1" --add --after 0 --mode ro "$2"
  199. }
  200.  
  201. # List all modules in all directories (base, modules, optional)
  202. # and filter out unneeded optional modules (not specified by load= kernel parameter)
  203. # $1 = root directory of mounted DATAdir
  204. #
  205. list_modules()
  206. {
  207.    LOAD="`cmdline_value load`"
  208.    ls -A1d $1/base/*.mo $1/modules/*.mo $1/optional/*.mo 2>/dev/null | while read LINE; do
  209.       MODNAME="`basename $LINE .mo`"
  210.       if [ "$LOAD" != "*" -a "`echo $LINE | grep optional`" != "" -a "`echo $LOAD | egrep \"(^|,)$MODNAME(\\\$|,)\"`" = "" ]; then continue
  211.         else echo $LINE; fi
  212.    done
  213. }
  214.  
  215. # Insert one single .mo module to the union
  216. # $1 = union absolute path
  217. # $2 = module.mo full path
  218. # $3 = destination folder, where images will be mounted to
  219. #
  220. union_insert_module()
  221. {
  222.    TARGET="$3/`basename $2`"
  223.    if mountpoint $TARGET >/dev/null 2>&1; then continue; fi # skip mounted modules
  224.    mkdir -p $TARGET
  225.    mount_module $2 $TARGET
  226.    if [ $? -ne 0 ]; then echo "Cannot read module data. corrupted download?" >&2; return 1; fi
  227.    union_insert_dir $1 $TARGET
  228.    if [ $? -ne 0 ]; then echo "can't insert module to union" >&2; return 2; fi
  229.    basename $TARGET
  230. }
  231.  
  232. # Insert all .mo modules, in $2 directory and subdirectories, to the union
  233. # $1 = union absolute path (starting with /)
  234. # $2 = LiveCD data dir (with directories /base, /modules, etc.)
  235. # $3 = destination folder, where images will be mounted to
  236. #
  237. union_insert_modules()
  238. {
  239.    list_modules $2 | while read MODULE; do
  240.       echo -n " -> "
  241.       union_insert_module $1 $MODULE $3
  242.    done
  243. }
  244.  
  245. # Copy LiveCD modules to RAM directory
  246. # will copy only /boot, and module files from $1
  247. # $1 = data directory
  248. # $2 = target directory in RAM
  249. #
  250. copy_to_ram()
  251. {
  252.    cp -R "$1/boot" "$2" # kernel is not required but it's nice2have
  253.    list_modules "$1" | while read MODULE; do
  254.       TARGET="$2/`basename \`dirname $MODULE\``"
  255.       mkdir -p "$TARGET"
  256.       cp "$MODULE" "$TARGET"
  257.       if [ "$?" -ne 0 ]; then fatal "can't copy to RAM, not enough memory?"; fi
  258.    done
  259. }
  260.  
  261. # Copy content of "rootcopy" directory on the CD to $2 (union, usually)
  262. # $1 = source
  263. # $2 = destination
  264. #
  265. copy_rootchanges()
  266. {
  267.    cp -a $1/rootcopy/* $2 2>/dev/null # could be empty
  268. }
  269.  
  270. # ===========================================================
  271. # discovery functions
  272. # ===========================================================
  273.  
  274. # List all CD-ROMs
  275. # by using /proc entries
  276. #
  277. list_cdrom_devices()
  278. {
  279.    if [ "`cmdline_parameter nocd`" != "" ]; then return 1; fi
  280.    for CDDEVICE in `cat /proc/sys/dev/cdrom/info 2>/dev/null | head -n 3 | tail -n 1 | cut -d ":" -f 2`; do
  281.       echo "/dev/$CDDEVICE"
  282.    done
  283. }
  284.  
  285. # List all devices with filesystems
  286. # Return empty result when nohd parameter was given.
  287. #
  288. list_partition_devices()
  289. {
  290.    if [ "`cmdline_parameter nohd`" != "" ]; then return 1; fi
  291.    cat /proc/partitions | grep -v loop | sed -r "s/^[0-9 ]+/\\/dev\\//" | grep /dev/
  292. #   blkid | grep -v swap | cut -d : -f 1 | grep -v loop
  293. }
  294.  
  295. # List all disk devices
  296. #
  297. list_disk_devices()
  298. {
  299.    list_partition_devices | egrep -v "[0-9]"
  300. }
  301.  
  302. # List all partitions marked as Linux Swap
  303. #
  304. list_swap_devices()
  305. {
  306.    if [ "`cmdline_parameter nohd`" != "" ]; then return 1; fi
  307.    blkid -t TYPE="swap" | cut -d : -f 1
  308. }
  309.  
  310. # List all block devices
  311. #
  312. list_block_devices()
  313. {
  314.    list_cdrom_devices
  315.    list_partition_devices
  316. }
  317.  
  318. # Try to mount all disks, partitions and cdroms and Find where the LiveCD is.
  319. # If LiveCD found in the device, echo dirname of it's directory,
  320. # and leave the device mounted. Mounting is not ro, but without any argument.
  321. # $1 = directory where devices will be mounted
  322. #
  323. find_live_data_dir()
  324. {
  325.    list_block_devices | while read DEVICE; do
  326.       DIR="/$1/`basename $DEVICE`"
  327.       mount_device $DEVICE $DIR
  328.       if [ $? -ne 0 ]; then continue; fi
  329.       FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
  330.       if [ "$FOUND" = "" ]; then umount $DIR 2>/dev/null; rmdir $DIR 2>/dev/null
  331.       else dirname "$FOUND"; return 1; fi
  332.    done
  333. }
  334.  
  335. # ===========================================================
  336. # hardware preparation functions
  337. # ===========================================================
  338.  
  339. # Create block devices to /dev described by /sys entries
  340. #
  341. create_block_devices()
  342. {
  343.    echolog "creating /dev entries for block devices"
  344.    ls -A1d /sys/block/*/dev /sys/block/*/*/dev 2>/dev/null | grep -v loop | while read BLOCK; do
  345.       DEVICE="/dev/`basename \`dirname $BLOCK\``"
  346.       if [ ! -b $DEVICE ]; then
  347.          MINORMAJOR="`head -n 1 $BLOCK | tr ':' ' '`"
  348.          mknod $DEVICE b $MINORMAJOR
  349.       fi
  350.    done
  351. }
  352.  
  353. # modprobe kernel modules needed for the LiveCD
  354. #
  355. modprobe_essential_modules()
  356. {
  357.    echolog "starting loop device support"
  358.    modprobe_module loop max_loop=255
  359.    echolog "starting cdrom filesystem support"
  360.    modprobe_module isofs
  361.    echolog "starting squashfs support"
  362.    modprobe_module squashfs
  363.    echolog "starting unionfs support"
  364.    modprobe_module unionfs
  365.    echolog "starting vfat support"
  366.    modprobe_module nls_cp437
  367.    modprobe_module nls_iso8859-1
  368.    modprobe_module nls_iso8859-2
  369.    modprobe_module vfat
  370.    echolog "starting ntfs support"
  371.    modprobe_module ntfs
  372.    create_block_devices
  373. }
  374.  
  375. # modprobe kernel modules needed for USB masstorage devices
  376. #
  377. modprobe_usb_modules()
  378. {
  379.    echolog "starting USB support"
  380.    modprobe_module ehci-hcd
  381.    modprobe_module ohci-hcd
  382.    modprobe_module uhci-hcd
  383.    modprobe_module usb-storage
  384.    sleep 5
  385.    create_block_devices
  386. }
  387.  
  388. # enable/disable CD autoejecting when unmounted
  389. # $1 = 1|0 ... enable|disable
  390. #
  391. cd_autoeject()
  392. {
  393.    echo $1 >/proc/sys/dev/cdrom/autoeject
  394. }
  395.  
  396. # Disable DMA if nodma boot parameter is present
  397. #
  398. setup_dma()
  399. {
  400.    if [ ! "`cmdline_parameter nodma`" = "" ]; then
  401.       for DEVICE in `list_cdrom_devices` `list_disk_devices`; do
  402.          echolog "setting DMA support off for $DEVICE"
  403.          hdparm -d 0 $DEVICE
  404.       done
  405.    fi
  406. }
  407.  
  408. # update given line in fstab, add new values only if the device is not found
  409. # $1 = fstab file to parse
  410. # $2 = device name
  411. # $3 = mountpoint
  412. # $4 = filesystem
  413. # $5 = mount options
  414. #
  415. fstab_update_line()
  416. {
  417.    if [ "`cat \"$1\" | egrep \"^[[:space:]]*[^[:space:]]+[[:space:]]+$3\"`" = "" ]; then
  418.       echo "$2" "$3" "$4" "$5" 0 0 "$FSTABLLFLAG" >>$1
  419.    fi
  420. }
  421.  
  422. # create correct fstab file in $1/etc/fstab and create apropriate
  423. # mount directories in $1/mnt. Check for iocharset boot option,
  424. # if present, add iocharset to all DOS/Win filesystems (vfat,ntfs)
  425. # $1 = root directory (union)
  426. #
  427. fstab_update()
  428. {
  429.    IOCHARSET="`cmdline_value iocharset`"
  430.    FSTAB="$1/etc/fstab"
  431.    mkdir -p $1/etc $1/mnt
  432.    cat $FSTAB 2>/dev/null | grep -v "$FSTABLLFLAG" >$FSTAB~
  433.  
  434.    fstab_update_line $FSTAB~ tmpfs / tmpfs defaults
  435.    fstab_update_line $FSTAB~ devpts /dev/pts devpts gid=5,mode=620
  436.    fstab_update_line $FSTAB~ proc /proc proc defaults
  437.  
  438.    list_cdrom_devices | while read DEVICE; do
  439.       MOUNTDIR="/mnt/`basename $DEVICE`_cdrom"
  440.       mkdir -p $1/$MOUNTDIR
  441.       fstab_update_line $FSTAB~ $DEVICE $MOUNTDIR iso9660 noauto,users,exec
  442.    done
  443.  
  444.    list_partition_devices | while read DEVICE; do
  445.       unset REMOVABLE; unset OPT; DEV="`basename $DEVICE`"; DEV0="`echo $DEV | cut -b 1-3`"
  446.       if [ "0`cat /sys/block/$DEV0/removable 2>/dev/null`" -ne 0 ]; then
  447.          REMOVABLE="_removable"
  448.       fi
  449.  
  450.       MOUNTDIR="/mnt/$DEV$REMOVABLE"
  451.       FS="`blkid -s TYPE $DEVICE | cut -d = -f 2 | tr -d ' \"'`"
  452.       if [ "$FS" = "ntfs" -a "$IOCHARSET" != "" ]; then OPT=",nls=$IOCHARSET"; fi
  453.       if [ "$FS" = "vfat" -a "$IOCHARSET" != ""  ]; then OPT=",iocharset=$IOCHARSET"; fi
  454.  
  455.       if [ "$FS" != "" ]; then
  456.          fstab_update_line $FSTAB~ $DEVICE $MOUNTDIR $FS auto,users,suid,dev,exec$OPT
  457.          mkdir -p "$1/$MOUNTDIR"
  458.       fi
  459.    done
  460.  
  461.    list_swap_devices | while read DEVICE; do
  462.       fstab_update_line $FSTAB~ $DEVICE swap swap defaults
  463.    done
  464.  
  465.    fstab_update_line $FSTAB~ /dev/fd0 /mnt/floppy vfat,msdos noauto,users,suid,dev,exec
  466.    mkdir -p $1/mnt/floppy
  467.    
  468.    mv -f $FSTAB~ $FSTAB
  469. }
  470.